package org.springblade.tms.module.statementorder.base;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.apache.logging.log4j.util.Strings;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.tms.global.enums.*;
import org.springblade.tms.global.exception.CommonException;
import org.springblade.tms.module.billing.entity.TMBilling;
import org.springblade.tms.module.billing.service.IBillingService;
import org.springblade.tms.module.demandextrainfo.entity.TmDemandExtraInfo;
import org.springblade.tms.module.demandextrainfo.service.ITmDemandExtraInfoService;
import org.springblade.tms.module.demandorder.entity.TMDemandOrder;
import org.springblade.tms.module.demandorder.service.IDemandOrderService;
import org.springblade.tms.module.demandorderitem.entity.TMDemandOrderItem;
import org.springblade.tms.module.demandorderitem.service.IDemandOrderItemService;
import org.springblade.tms.module.sap.base.SapRequestService;
import org.springblade.tms.module.sap.dto.SapFreightStatementDTO;
import org.springblade.tms.module.sap.dto.SapFreightStatementDataItem;
import org.springblade.tms.module.sap.dto.SapFreightStatementItemDTO;
import org.springblade.tms.module.signedinfo.entity.TMSignedInfo;
import org.springblade.tms.module.signedinfo.service.ISignedInfoService;
import org.springblade.tms.module.statementorder.dto.SettlementSheetDTO;
import org.springblade.tms.module.statementorder.entity.TMStatementOrder;
import org.springblade.tms.module.statementorder.service.IStatementOrderService;
import org.springblade.tms.module.statementorder.vo.TMStatementOrderVO;
import org.springblade.tms.module.statementorder.wrapper.StatementOrderWrapper;
import org.springblade.tms.module.transportorder.entity.TMTransportOrder;
import org.springblade.tms.module.transportorder.service.ITransportOrderService;
import org.springblade.tms.module.transportorderitem.entity.TMTransportOrderItem;
import org.springblade.tms.module.transportorderitem.service.ITransportOrderItemService;
import org.springblade.tms.module.userinfo.base.DriverManagementService;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @projectName: BladeX
 * @package: org.springblade.tms.module.statementorder.base
 * @className: SettlementSheetService
 * @author: yr
 * @description: 结算单服务
 * @date: 2022/3/30 10:12
 */
@Service
@Transactional
public class SettlementSheetService {
	@Resource
	private IStatementOrderService statementOrderService;
	@Resource
	private IDemandOrderService demandOrderService;
	@Resource
	private ITmDemandExtraInfoService tmDemandExtraInfoService;
	@Resource
	private ITransportOrderService transportOrderService;
	@Resource
	private SapRequestService sapRequestService;
	@Resource
	private DriverManagementService driverManagementService;
	@Resource
	private IBillingService billingService;
	@Resource
	private ITransportOrderItemService transportOrderItemService;
	@Resource
	private IDemandOrderItemService demandOrderItemService;
	@Resource
	private ISignedInfoService signedInfoService;

	/**
	 * @param settlementSheetDTO:
	 * @param query:
	 * @return R<IPage               <               TMStatementOrderVO>>
	 * @author yr
	 * @description 结算单列表
	 * @date 2022/3/30 13:45
	 */
	public R<IPage<TMStatementOrderVO>> list(SettlementSheetDTO settlementSheetDTO, Query query) {
		if (settlementSheetDTO == null) {
			settlementSheetDTO = new SettlementSheetDTO();
		}
		Date currentDate = DateUtil.plusMonths(DateUtil.now(), -12);
		//根据条件查出需求单和运输单
		List<TMDemandOrder> tmDemandOrders = demandOrderService.lambdaQuery()
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMDemandOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
			.like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMDemandOrder::getCarrierName, settlementSheetDTO.getCarrierName())
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMDemandOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
			.like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMDemandOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote())
			.gt(TMDemandOrder::getPlanGetGoodsDateStart, currentDate).list();
		List<TMTransportOrder> tmTransportOrders = transportOrderService.lambdaQuery()
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMTransportOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
			.like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMTransportOrder::getCarrierName, settlementSheetDTO.getCarrierName())
			.like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMTransportOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote())
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMTransportOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
			.like(Strings.isNotBlank(settlementSheetDTO.getShippingNoteNumber()), TMTransportOrder::getTransportNo, settlementSheetDTO.getShippingNoteNumber())
			.gt(TMTransportOrder::getPlanGetGoodsDateStart, currentDate).list();
		//获取运单和需求单id

		List<Long> demandOrderIds = tmDemandOrders.stream().map(TMDemandOrder::getId).collect(Collectors.toList());
		List<Long> transportOrderIds = tmTransportOrders.stream().map(TMTransportOrder::getId).collect(Collectors.toList());
		//根据需求单和运单查询出结算单
		TMUserInfo tmUserInfo = driverManagementService.getTmUserInfo();
		SettlementSheetDTO finalSettlementSheetDTO = settlementSheetDTO;
		LambdaQueryWrapper<TMStatementOrder> tmStatementOrderLambdaQueryWrapper = Condition.getQueryWrapper(new TMStatementOrder()).lambda()
			.eq(TMStatementOrder::getNo, "")
			.eq(TMStatementOrder::getStaging, finalSettlementSheetDTO.getStaging())
			.and(LambdaQueryWrapper -> LambdaQueryWrapper
				.in(!transportOrderIds.isEmpty(), TMStatementOrder::getParentId, transportOrderIds).or()
				.in(!demandOrderIds.isEmpty(), TMStatementOrder::getParentId, demandOrderIds)
				.apply(demandOrderIds.isEmpty() && transportOrderIds.isEmpty(), "1=2"))
//			.groupBy(TMStatementOrder::getParentId)
			.orderByDesc(TMStatementOrder::getCreateTime, TMStatementOrder::getId);
		if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			tmStatementOrderLambdaQueryWrapper = tmStatementOrderLambdaQueryWrapper.eq(TMStatementOrder::getCarrierNo, tmUserInfo.getTmId());
		}
		IPage<TMStatementOrder> statementOrderIPage = statementOrderService.page(Condition.getPage(query), tmStatementOrderLambdaQueryWrapper);
		IPage<TMStatementOrderVO> tmStatementOrderVOIPage = StatementOrderWrapper.build().pageVO(statementOrderIPage);
		List<TMStatementOrderVO> statementOrderVOS = tmStatementOrderVOIPage.getRecords();
		//根据需求单和运输单id查询出物料信息
		List<TMTransportOrderItem> tmTransportOrderItems = transportOrderItemService.lambdaQuery()
			.in(!transportOrderIds.isEmpty(), TMTransportOrderItem::getParentId, transportOrderIds).list();
		List<TMDemandOrderItem> tmDemandOrderItems = demandOrderItemService.lambdaQuery()
			.in(!demandOrderIds.isEmpty(), TMDemandOrderItem::getParentId, demandOrderIds).list();
		Map<Long, List<TMDemandOrderItem>> demandOrderItemMap = tmDemandOrderItems.stream().collect(Collectors.groupingBy(TMDemandOrderItem::getParentId));
		Map<Long, List<TMTransportOrderItem>> transportItemMap = tmTransportOrderItems.stream().collect(Collectors.groupingBy(TMTransportOrderItem::getParentId));

		Map<Long, List<TMDemandOrder>> DemandOrderMap = tmDemandOrders.stream().collect(Collectors.groupingBy(TMDemandOrder::getId));
		Map<Long, List<TMTransportOrder>> transportOrderMap = tmTransportOrders.stream().collect(Collectors.groupingBy(TMTransportOrder::getId));
		//结算单vo数据封装
		List<TMSignedInfo> tmSignedInfos = signedInfoService.lambdaQuery().in(!transportOrderIds.isEmpty(), TMSignedInfo::getParentId, transportOrderIds).list();
		Map<Long, List<TMSignedInfo>> signedInfoMapByPrentId = tmSignedInfos.stream().collect(Collectors.groupingBy(TMSignedInfo::getParentId));
		for (TMStatementOrderVO statementOrderVO : statementOrderVOS) {
			if (statementOrderVO.getOrderType().equals(OrderTypeEnum.SINGLE_TRANSPORT.value())) {
				TMTransportOrder tmTransportOrder = transportOrderMap.get(statementOrderVO.getParentId()).get(0);
				statementOrderVO.setShippingNoteNumber(tmTransportOrder.getTransportNo());
				statementOrderVO.setDemandOrderNumber(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getDemandOrderNumber());
				statementOrderVO.setWerks(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getWerks());
				statementOrderVO.setFreightOrder(tmTransportOrder.getOrderNo());
				statementOrderVO.setFreightOrderType(tmTransportOrder.getOrderType());
				statementOrderVO.setDeliverNo(tmTransportOrder.getDeliverNo());
				statementOrderVO.setCarrierName(tmTransportOrder.getCarrierName());
				statementOrderVO.setLicensePlateNumber(tmTransportOrder.getCarNo());
				statementOrderVO.setDriver(tmTransportOrder.getDriverName());
				statementOrderVO.setBillOfLadingNumber(tmTransportOrder.getBillOfLadingNumber());
				statementOrderVO.setCustomerName(tmTransportOrder.getCustomerName());
				statementOrderVO.setStartLocationName(tmTransportOrder.getStartLocationName());
				List<TMSignedInfo> signedInfos = signedInfoMapByPrentId.get(tmTransportOrder.getId());
				if (signedInfos != null) {
					TMSignedInfo tmSignedInfo = signedInfos.get(0);
					assert tmSignedInfo != null;
					statementOrderVO.setNum(tmSignedInfo.getNum());
				}
				//封装源位置和物料
				statementOrderVO.setSourceLocationStreet(new StringBuilder(tmTransportOrder.getStartLocationArea())
					.append(tmTransportOrder.getStartLocationCity()).append(tmTransportOrder.getStartLocationStreet()).toString());
				statementOrderVO.setDestinationStreet(new StringBuilder(tmTransportOrder.getTargetLocationArea())
					.append(tmTransportOrder.getTargetLocationCity()).append(tmTransportOrder.getTargetLocationStreet()).toString());
				transportItemMap.get(tmTransportOrder.getId()).forEach(item -> {
					statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
						.append("*").append(item.getNum().toString()).append("(")
						.append(item.getUnit()).append(")").toString());
				});
			} else {
				TMDemandOrder tmDemandOrder = DemandOrderMap.get(statementOrderVO.getParentId()).get(0);
				statementOrderVO.setDemandOrderNumber(tmDemandOrder.getDemandOrderNumber());
				statementOrderVO.setFreightOrder(tmDemandOrder.getOrderNo());
				statementOrderVO.setWerks(tmDemandOrder.getWerks());
				statementOrderVO.setFreightOrderType(tmDemandOrder.getOrderType());
				statementOrderVO.setDeliverNo(tmDemandOrder.getDeliverNo());
				statementOrderVO.setCarrierName(tmDemandOrder.getCarrierName());
				statementOrderVO.setBillOfLadingNumber(tmDemandOrder.getBillOfLadingNumber());
				statementOrderVO.setCustomerName(tmDemandOrder.getCustomerName());
				statementOrderVO.setStartLocationName(tmDemandOrder.getStartLocationName());
				//封装源位置和物料
				statementOrderVO.setSourceLocationStreet(new StringBuilder(tmDemandOrder.getStartLocationArea())
					.append(tmDemandOrder.getStartLocationCity()).append(tmDemandOrder.getStartLocationStreet()).toString());
				statementOrderVO.setDestinationStreet(new StringBuilder(tmDemandOrder.getTargetLocationArea())
					.append(tmDemandOrder.getTargetLocationCity()).append(tmDemandOrder.getTargetLocationStreet()).toString());
				demandOrderItemMap.get(tmDemandOrder.getId()).forEach(item -> {
					statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
						.append("*").append(item.getNum().toString()).append("(")
						.append(item.getUnit()).append(")").toString());
				});
			}
			//货运订单号去0
			statementOrderVO.setFreightOrder(Long.toString(Long.parseLong(statementOrderVO.getFreightOrder())));
		}
		statementOrderVOS.forEach(tmStatementOrderVO -> tmStatementOrderVO.setOrderType(OrderTypeEnum.getDescriptionByValue(tmStatementOrderVO.getOrderType())));
//		//封装运费
//		Map<Long, List<TMStatementOrderVO>> statementOrderVOSMap = statementOrderVOS.stream().collect(Collectors.groupingBy(TMStatementOrder::getParentId));
//		List<TMStatementOrder> tmStatementOrders = statementOrderService.lambdaQuery().in(!demandOrderIds.isEmpty(), TMStatementOrder::getParentId, demandOrderIds).or()
//			.in(!transportOrderIds.isEmpty(), TMStatementOrder::getParentId, transportOrderIds)
//			.apply(demandOrderIds.isEmpty() && transportOrderIds.isEmpty(), "1=2")
//			.orderByDesc(TMStatementOrder::getCreateTime).list();
//		Map<Long, List<TMStatementOrder>> tmStatementOrderMap = tmStatementOrders.stream().collect(Collectors.groupingBy(TMStatementOrder::getParentId));
//		for (Long id : statementOrderVOSMap.keySet()) {
//			BigDecimal sum = tmStatementOrderMap.get(id).stream().map(TMStatementOrder::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
//			statementOrderVOSMap.get(id).get(0).setMoney(sum);
//		}
		return R.data(tmStatementOrderVOIPage);
	}

	/**
	 * 暂存
	 *
	 * @param ids
	 * @return
	 */
	public R<Boolean> staging(String ids) {
		List<Long> longs = Func.toLongList(ids);
		List<TMStatementOrder> tmStatementOrders = statementOrderService.lambdaQuery().in(TMStatementOrder::getId, longs).list();
		//将暂存修改为是
		if (!tmStatementOrders.isEmpty() && tmStatementOrders.get(0).getStaging().equals(false)) {
			tmStatementOrders.forEach(tmStatementOrder -> {
				tmStatementOrder.setStaging(true);
			});
			statementOrderService.updateBatchById(tmStatementOrders);
			return R.data(true);
		}
		return R.data(false);
	}

	/**
	 * @param :
	 * @param ids
	 * @return R<Boolean>
	 * @author yr
	 * @description 确认运费
	 * @date 2022/3/30 13:54
	 */
	public R<Boolean> confirmShipping(String ids) {
		List<Long> longs = Func.toLongList(ids);
		List<TMStatementOrder> tmStatementOrders = statementOrderService.lambdaQuery().in(TMStatementOrder::getId, longs).list();
		//将暂存修改为是
		Map<Long, List<TMStatementOrder>> StatementOrderMap = tmStatementOrders.stream().collect(Collectors.groupingBy(TMStatementOrder::getParentId));
		//需求单上报
		Map<String, List<TMStatementOrder>> tmStatementOrderMap = tmStatementOrders.stream().collect(Collectors.groupingBy(TMStatementOrder::getOrderType));
		List<SapFreightStatementDTO> sapFreightStatementDTOs = new ArrayList<>();
		List<TMStatementOrder> statementOrderList1 = tmStatementOrderMap.get(OrderTypeEnum.DEMAND_LIST.value());
		if (statementOrderList1 == null) {
			statementOrderList1 = new ArrayList<>();
		}
		List<Long> statementOrderIds1 = statementOrderList1.stream().map(TMStatementOrder::getParentId).collect(Collectors.toList());
		List<TMDemandOrder> tmDemandOrders = demandOrderService.lambdaQuery()
			.in(!statementOrderIds1.isEmpty(), TMDemandOrder::getId, statementOrderIds1)
			.apply(statementOrderIds1.isEmpty(), "1=2")
			.list();
		tmDemandOrders.forEach(tmDemandOrder -> {
			if (!tmDemandOrder.getDemandStatus().equals(DemandStatusEnum.FINISH.value())) {
				CommonException.throwCommonException("货运订单：" + tmDemandOrder.getOrderNo() + "未完成，不能确认运费");
			}
		});
		for (TMDemandOrder tmDemandOrder : tmDemandOrders) {
			StatementOrderMap.get(tmDemandOrder.getId()).forEach(tmStatementOrder -> {
				SapFreightStatementDTO sapFreightStatementDTO = new SapFreightStatementDTO();
				SapFreightStatementItemDTO sapFreightStatementItemDTO = new SapFreightStatementItemDTO();
				sapFreightStatementItemDTO.setOrderType(tmDemandOrder.getOrderType());
				sapFreightStatementItemDTO.setOrderNo(tmDemandOrder.getOrderNo());
				sapFreightStatementItemDTO.setChargeType(tmStatementOrder.getChargeType());
				sapFreightStatementDTO.getItem().add(sapFreightStatementItemDTO);
				sapFreightStatementDTO.setType(OrderTypeEnum.DEMAND_LIST.value());
				sapFreightStatementDTOs.add(sapFreightStatementDTO);
			});
		}
		//运输单上报
		List<TMStatementOrder> statementOrderList2 = tmStatementOrderMap.get(OrderTypeEnum.SINGLE_TRANSPORT.value());
		if (statementOrderList2 == null) {
			statementOrderList2 = new ArrayList<>();
		}
		List<Long> statementOrderIds2 = statementOrderList2.stream().map(TMStatementOrder::getParentId).collect(Collectors.toList());
		List<TMTransportOrder> transportOrders = transportOrderService.lambdaQuery()
			.in(!statementOrderIds2.isEmpty(), TMTransportOrder::getId, statementOrderIds2)
			.apply(statementOrderIds2.isEmpty(), "1=2")
			.list();
		transportOrders.forEach(tmTransportOrder -> {
			if (!tmTransportOrder.getTransportStatus().equals(WaybillStatusEnum.COMPLETED.value())) {
				CommonException.throwCommonException("货运订单：" + tmTransportOrder.getOrderNo() + "未完成，不能确认运费");
			}
		});
		for (TMTransportOrder transportOrder : transportOrders) {
			StatementOrderMap.get(transportOrder.getId()).forEach(tmStatementOrder -> {
				SapFreightStatementDTO sapFreightStatementDTO = new SapFreightStatementDTO();
				SapFreightStatementItemDTO sapFreightStatementItemDTO = new SapFreightStatementItemDTO();
				sapFreightStatementItemDTO.setOrderNoNew(transportOrder.getOrderNoNew());
				sapFreightStatementItemDTO.setOrderType(transportOrder.getOrderType());
				sapFreightStatementItemDTO.setTransportNo(transportOrder.getTransportNo());
				sapFreightStatementItemDTO.setChargeType(tmStatementOrder.getChargeType());
				sapFreightStatementDTO.setType(OrderTypeEnum.SINGLE_TRANSPORT.value());
				sapFreightStatementDTO.getItem().add(sapFreightStatementItemDTO);
				sapFreightStatementDTOs.add(sapFreightStatementDTO);
			});
		}
		Map<String, List<SapFreightStatementDataItem>> freightStatementMap = sapRequestService.freightStatement(sapFreightStatementDTOs)
			.stream().collect(Collectors.groupingBy(SapFreightStatementDataItem::getSfirId));
		if (tmStatementOrderMap.get(OrderTypeEnum.SINGLE_TRANSPORT.value()) != null) {
			//封装预结算单
			Map<String, List<TMTransportOrder>> transportOrderMap = transportOrders.stream().collect(Collectors.groupingBy(TMTransportOrder::getOrderNoNew));
			//运单id为key，结算单号为值
			HashMap<String, String> map = new HashMap<>();
			//运单id为key，失败原因为值
			HashMap<String, String> map1 = new HashMap<>();
			//运单id为key，行项目号为值
			HashMap<String, String> map2 = new HashMap<>();
			freightStatementMap.keySet().stream().forEach(key -> {
					freightStatementMap.get(key).forEach(sapFreightStatementDataItem -> {
						if (!sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFB1.getValue()) &
							!sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFB2.getValue()) &
							!sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFO9.getValue()) &
							!sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFO3.getValue())
						) {
							Long id = transportOrderMap.get(sapFreightStatementDataItem.getTorId().toString()).get(0).getId();
							String sfirId = sapFreightStatementDataItem.getSfirId();
							String itemID = sapFreightStatementDataItem.getItemId();
							String chargeTypeAddId = new StringBuilder(sapFreightStatementDataItem.getChargeType()).append(id).toString();
							if (Strings.isNotBlank(sfirId)) {
								map.put(chargeTypeAddId, sfirId);
								map2.put(chargeTypeAddId, itemID);
							} else {
								map1.put(chargeTypeAddId, sapFreightStatementDataItem.getText());
							}
						}
					});
				}
			);
			statementOrderList2.forEach(tmStatementOrder -> {
				tmStatementOrder.setOrderType(tmStatementOrder.getOrderType());
				String chargeTypeAddId = new StringBuilder(tmStatementOrder.getChargeType()).append(tmStatementOrder.getParentId()).toString();
				if (Strings.isNotBlank(map.get(chargeTypeAddId))) {
					tmStatementOrder.setNo(map.get(chargeTypeAddId));
					tmStatementOrder.setItemId(map2.get(chargeTypeAddId));
				} else {
					tmStatementOrder.setReason(map1.get(chargeTypeAddId));
				}
			});
			statementOrderService.updateBatchById(statementOrderList2);
		}
		if (tmStatementOrderMap.get(OrderTypeEnum.DEMAND_LIST.value()) != null) {
			//封装预结算单
			Map<String, List<TMDemandOrder>> tmDemandOrderMap = tmDemandOrders.stream().collect(Collectors.groupingBy(TMDemandOrder::getOrderNo));
			//运单id为key，结算单号为值
			HashMap<String, String> map = new HashMap<>();
			//运单id为key，失败原因为值
			HashMap<String, String> map1 = new HashMap<>();
			//运单id为key，行项目号为值
			HashMap<String, String> map2 = new HashMap<>();
			freightStatementMap.keySet().stream().forEach(key -> {
					freightStatementMap.get(key).forEach(sapFreightStatementDataItem -> {
						if (sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFB1.getValue()) ||
							sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFB2.getValue()) ||
							sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFO9.getValue()) ||
							sapFreightStatementDataItem.getTorType().equals(TorTypeEnum.ZFO3.getValue())
						) {
							Long id = tmDemandOrderMap.get(sapFreightStatementDataItem.getTorId().toString()).get(0).getId();
							String chargeTypeAddId = new StringBuilder(sapFreightStatementDataItem.getChargeType()).append(id).toString();
							if (sapFreightStatementDataItem.getId().equals(SapMsgStatusEnum.S.value())) {
								String sfirId = sapFreightStatementDataItem.getSfirId();
								String itemID = sapFreightStatementDataItem.getItemId();
								map.put(chargeTypeAddId, sfirId);
								map2.put(chargeTypeAddId, itemID);
							} else {
								String text = sapFreightStatementDataItem.getText();
								map1.put(chargeTypeAddId, text);
							}
						}
					});
				}
			);
			statementOrderList1.forEach(tmStatementOrder -> {
				String chargeTypeAddId = new StringBuilder(tmStatementOrder.getChargeType()).append(tmStatementOrder.getParentId()).toString();
				if (Strings.isNotBlank(map.get(chargeTypeAddId))) {
					tmStatementOrder.setNo(map.get(chargeTypeAddId));
					tmStatementOrder.setItemId(map2.get(chargeTypeAddId));
				} else {
					tmStatementOrder.setReason(map1.get(chargeTypeAddId));
				}
				tmStatementOrder.setOrderType(tmStatementOrder.getOrderType());
			});
			statementOrderService.updateBatchById(statementOrderList1);
		}
		//封装结算单
		statementOrderList1.addAll(statementOrderList2);
		Map<String, List<TMStatementOrder>> statementOrderMap = statementOrderList1.stream().collect(Collectors.groupingBy(TMStatementOrder::getNo));
		ArrayList<TMBilling> billings = new ArrayList<>();
		statementOrderMap.keySet().forEach(s -> {
			if (Strings.isNotBlank(s)) {
				List<TMStatementOrder> statementOrders = statementOrderMap.get(s);
				TMBilling tmBilling = new TMBilling();
				tmBilling.setNo(s);
				BigDecimal price = statementOrders.stream().map(TMStatementOrder::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
				tmBilling.setPrice(price);
				tmBilling.setPayStatus(statementOrders.get(0).getFsdPost());
				tmBilling.setPostingDate(LocalDateTime.now());
				tmBilling.setCarrierNo(statementOrders.get(0).getCarrierNo());
				tmBilling.setContractCompany(statementOrders.get(0).getContractCompany());
				tmBilling.setDocCurrency(statementOrders.get(0).getDocCurrency());
				if (tmBilling.getPayStatus() != null && tmBilling.getPayStatus().equals("X")) {
					tmBilling.setFsdPur("X");
				}
				billings.add(tmBilling);
			}
		});
		billingService.saveOrUpdateBatch(billings);
		return R.status(true);
	}

	/**
	 * @return 导出的数据
	 */
	public List<TMStatementOrderVO> export(SettlementSheetDTO settlementSheetDTO) {
		if (settlementSheetDTO == null) {
			settlementSheetDTO = new SettlementSheetDTO();
		}
		//根据条件查出需求单和运输单
		List<TMDemandOrder> tmDemandOrders = demandOrderService.lambdaQuery()
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMDemandOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
			.like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMDemandOrder::getCarrierName, settlementSheetDTO.getCarrierName())
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMDemandOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
			.like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMDemandOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote()).list();
		List<TMTransportOrder> tmTransportOrders = transportOrderService.lambdaQuery()
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMTransportOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
			.like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMTransportOrder::getCarrierName, settlementSheetDTO.getCarrierName())
			.like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMTransportOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote())
			.like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMTransportOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
			.like(Strings.isNotBlank(settlementSheetDTO.getShippingNoteNumber()), TMTransportOrder::getTransportNo, settlementSheetDTO.getShippingNoteNumber()).list();
		//根据条件查出需求单和运输单
		//获取运单和需求单id
		List<Long> demandOrderIds = tmDemandOrders.stream().map(TMDemandOrder::getId).collect(Collectors.toList());
		List<Long> transportOrderIds = tmTransportOrders.stream().map(TMTransportOrder::getId).collect(Collectors.toList());
		//获取所有需求单的补充信息，用于获取需求单的罐箱号
		Map<Long, List<TmDemandExtraInfo>> demandExtraInfoMapByParentId = new HashMap<>();
		if (demandOrderIds != null && !demandOrderIds.isEmpty()) {
			List<TmDemandExtraInfo> tmDemandExtraInfos = tmDemandExtraInfoService.lambdaQuery().in(TmDemandExtraInfo::getParentId, demandOrderIds).list();
			demandExtraInfoMapByParentId = tmDemandExtraInfos.stream().collect(Collectors.groupingBy(TmDemandExtraInfo::getParentId));
		}
		//根据需求单和运单查询出结算单
		TMUserInfo tmUserInfo = driverManagementService.getTmUserInfo();
		LambdaQueryChainWrapper<TMStatementOrder> tmStatementOrderLambdaQueryChainWrapper = statementOrderService.lambdaQuery().eq(TMStatementOrder::getNo, "")
			.and(LambdaQueryWrapper -> LambdaQueryWrapper.in(!transportOrderIds.isEmpty(), TMStatementOrder::getParentId, transportOrderIds).or()
				.in(!demandOrderIds.isEmpty(), TMStatementOrder::getParentId, demandOrderIds)
				.apply(demandOrderIds.isEmpty() && transportOrderIds.isEmpty(), "1=2"))
			.orderByDesc(TMStatementOrder::getCreateTime, TMStatementOrder::getId);
		if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			tmStatementOrderLambdaQueryChainWrapper.eq(TMStatementOrder::getCarrierNo, tmUserInfo.getTmId());
		}
		List<TMStatementOrder> tmStatementOrders = tmStatementOrderLambdaQueryChainWrapper.list();
		List<TMStatementOrderVO> statementOrderVOS = BeanUtil.copy(tmStatementOrders, TMStatementOrderVO.class);
		//根据需求单和运输单id查询出物料信息
		List<TMTransportOrderItem> tmTransportOrderItems = transportOrderItemService.lambdaQuery()
			.in(!transportOrderIds.isEmpty(), TMTransportOrderItem::getParentId, transportOrderIds).list();
		List<TMDemandOrderItem> tmDemandOrderItems = demandOrderItemService.lambdaQuery()
			.in(!demandOrderIds.isEmpty(), TMDemandOrderItem::getParentId, demandOrderIds).list();
		Map<Long, List<TMDemandOrderItem>> demandOrderItemMap = tmDemandOrderItems.stream().collect(Collectors.groupingBy(TMDemandOrderItem::getParentId));
		Map<Long, List<TMTransportOrderItem>> transportItemMap = tmTransportOrderItems.stream().collect(Collectors.groupingBy(TMTransportOrderItem::getParentId));

		Map<Long, List<TMDemandOrder>> DemandOrderMap = tmDemandOrders.stream().collect(Collectors.groupingBy(TMDemandOrder::getId));
		Map<Long, List<TMTransportOrder>> transportOrderMap = tmTransportOrders.stream().collect(Collectors.groupingBy(TMTransportOrder::getId));
		//结算单vo数据封装
		List<TMSignedInfo> tmSignedInfos = signedInfoService.lambdaQuery().in(!transportOrderIds.isEmpty(), TMSignedInfo::getParentId, transportOrderIds).list();
		Map<Long, List<TMSignedInfo>> signedInfoMapByPrentId = tmSignedInfos.stream().collect(Collectors.groupingBy(TMSignedInfo::getParentId));
		for (TMStatementOrderVO statementOrderVO : statementOrderVOS) {
			if (statementOrderVO.getOrderType().equals(OrderTypeEnum.SINGLE_TRANSPORT.value())) {
				TMTransportOrder tmTransportOrder = transportOrderMap.get(statementOrderVO.getParentId()).get(0);
				statementOrderVO.setShippingNoteNumber(tmTransportOrder.getTransportNo());
				statementOrderVO.setDemandOrderNumber(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getDemandOrderNumber());
				statementOrderVO.setWerks(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getWerksName());
				statementOrderVO.setFreightOrder(tmTransportOrder.getOrderNo());
				statementOrderVO.setFreightOrderType(tmTransportOrder.getOrderType());
				statementOrderVO.setContainerNo(tmTransportOrder.getContainerNo());
				statementOrderVO.setDeliverNo(tmTransportOrder.getDeliverNo());
				statementOrderVO.setCarrierName(tmTransportOrder.getCarrierName());
				statementOrderVO.setLicensePlateNumber(tmTransportOrder.getCarNo());
				statementOrderVO.setDriver(tmTransportOrder.getDriverName());
				statementOrderVO.setBillOfLadingNumber(tmTransportOrder.getBillOfLadingNumber());
				statementOrderVO.setCustomerName(tmTransportOrder.getCustomerName());
				statementOrderVO.setStartLocationName(tmTransportOrder.getStartLocationName());
				List<TMSignedInfo> signedInfos = signedInfoMapByPrentId.get(tmTransportOrder.getId());
				if (signedInfos != null) {
					TMSignedInfo tmSignedInfo = signedInfos.get(0);
					assert tmSignedInfo != null;
					statementOrderVO.setNum(tmSignedInfo.getNum());
				}
				//封装源位置和物料
				statementOrderVO.setSourceLocationStreet(new StringBuilder(tmTransportOrder.getStartLocationArea())
					.append(tmTransportOrder.getStartLocationCity()).append(tmTransportOrder.getStartLocationStreet()).toString());
				statementOrderVO.setDestinationStreet(new StringBuilder(tmTransportOrder.getTargetLocationArea())
					.append(tmTransportOrder.getTargetLocationCity()).append(tmTransportOrder.getTargetLocationStreet()).toString());
				transportItemMap.get(tmTransportOrder.getId()).forEach(item -> {
					statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
						.append("*").append(item.getNum().toString()).append("(")
						.append(item.getUnit()).append(")").toString());
				});
			} else {
				TMDemandOrder tmDemandOrder = DemandOrderMap.get(statementOrderVO.getParentId()).get(0);
				statementOrderVO.setDemandOrderNumber(tmDemandOrder.getDemandOrderNumber());
				statementOrderVO.setFreightOrder(tmDemandOrder.getOrderNo());
				statementOrderVO.setWerks(tmDemandOrder.getWerks());
				statementOrderVO.setFreightOrderType(tmDemandOrder.getOrderType());
				statementOrderVO.setDeliverNo(tmDemandOrder.getDeliverNo());
				statementOrderVO.setCarrierName(tmDemandOrder.getCarrierName());
				statementOrderVO.setBillOfLadingNumber(tmDemandOrder.getBillOfLadingNumber());
				statementOrderVO.setCustomerName(tmDemandOrder.getCustomerName());
				statementOrderVO.setStartLocationName(tmDemandOrder.getStartLocationName());
				List<TmDemandExtraInfo> tmDemandExtraInfos = demandExtraInfoMapByParentId.get(tmDemandOrder.getId());
				if (tmDemandExtraInfos != null && !tmDemandExtraInfos.isEmpty()) {
					statementOrderVO.setContainerNo(tmDemandExtraInfos.get(0).getContainerNo());
				}
				//封装源位置和物料
				statementOrderVO.setSourceLocationStreet(new StringBuilder(tmDemandOrder.getStartLocationArea())
					.append(tmDemandOrder.getStartLocationCity()).append(tmDemandOrder.getStartLocationStreet()).toString());
				statementOrderVO.setDestinationStreet(new StringBuilder(tmDemandOrder.getTargetLocationArea())
					.append(tmDemandOrder.getTargetLocationCity()).append(tmDemandOrder.getTargetLocationStreet()).toString());
				demandOrderItemMap.get(tmDemandOrder.getId()).forEach(item -> {
					statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
						.append("*").append(item.getNum().toString()).append("(")
						.append(item.getUnit()).append(")").toString());
				});
			}
			//货运订单号去0
			statementOrderVO.setFreightOrder(Long.toString(Long.parseLong(statementOrderVO.getFreightOrder())));
		}
		statementOrderVOS.forEach(tmStatementOrderVO -> tmStatementOrderVO.setOrderType(OrderTypeEnum.getDescriptionByValue(tmStatementOrderVO.getOrderType())));
		return statementOrderVOS;
	}
//
//	/**
//	 * @param query:
//	 * @return R<IPage < ChargeDetailsVo>>
//	 * @author yr
//	 * @description 运费明细服务
//	 * @date 2022/4/13 16:56
//	 */
//	public R<IPage<ChargeDetailsVo>> chargeDetails(Long id, Query query) {
//		IPage<TMStatementOrder> statementOrderIPage = statementOrderService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMStatementOrder())
//			.lambda().eq(TMStatementOrder::getParentId, id));
//		List<ChargeDetailsVo> chargeDetailsVos = new ArrayList<>();
//		for (TMStatementOrder statementOrder : statementOrderIPage.getRecords()) {
//			ChargeDetailsVo chargeDetailsVo = BeanUtil.copy(statementOrder, ChargeDetailsVo.class);
//			chargeDetailsVos.add(chargeDetailsVo);
//		}
//		IPage<ChargeDetailsVo> chargeDetailsVoIPage = new Page(statementOrderIPage.getCurrent(), statementOrderIPage.getSize(), statementOrderIPage.getTotal());
//		chargeDetailsVoIPage.setRecords(chargeDetailsVos);
//		return R.data(chargeDetailsVoIPage);
//	}
}
